package be.tihh.mgmt.tasks;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//modified version of http://www.jibble.org/wake-on-lan/
public class WakeOnLan extends ComputerTask {

    public static final int PORT = 9;

    String broadCastAddress;

    public void execute() {
        super.execute();
        System.out.println("waking up "+computer);
        wakeOnLan(computer.getMacAddress());
    }

    public String getName() {
        return "WakeOnLan";
    }

    /**
     * Constructor for wake on lan
     * @param broadCastAddress the broadcast address to use
     */
    public WakeOnLan(String broadCastAddress) {
        this.broadCastAddress = broadCastAddress;
    }

    /**
     * Broadcasts a Wake On Lan (magic) packet.
     * @param macAddress mac address in format aa:bb:cc... or aa-bb-cc...
     */
    private void wakeOnLan(String macAddress) {

        String ipStr = broadCastAddress;

        try {
            byte[] macBytes = getMacBytes(macAddress);
            byte[] bytes = new byte[6 + 16 * macBytes.length];
            for (int i = 0; i < 6; i++) {
                bytes[i] = (byte) 0xff;
            }
            for (int i = 6; i < bytes.length; i += macBytes.length) {
                System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
            }

            InetAddress address = InetAddress.getByName(ipStr);
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, PORT);
            DatagramSocket socket = new DatagramSocket();
            socket.send(packet);
            socket.close();

//            System.out.println("Wake-on-LAN packet sent.");

            taskStatus.setStatus(TaskStatus.FINISHED_OK);
        }
        catch (Exception e) {
            System.out.println("Failed to send Wake-on-LAN packet: "+ e);
            //todo : throw exception
//            System.exit(1);
            taskStatus.setStatus(TaskStatus.FINISHED_NOK);
        }

    }

    private byte[] getMacBytes(String macStr) throws IllegalArgumentException {
        byte[] bytes = new byte[6];
        String[] hex = macStr.split("(\\:|\\-)");
        if (hex.length != 6) {
            throw new IllegalArgumentException("Invalid MAC address.");
        }
        try {
            for (int i = 0; i < 6; i++) {
                bytes[i] = (byte) Integer.parseInt(hex[i], 16);
            }
        }
        catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid hex digit in MAC address.");
        }
        return bytes;
    }

}
